package org.cycuchy.hp.app {
	
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.events.TimerEvent;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.Timer;
	
	import mx.core.Application;
	import mx.events.FlexEvent;
	import mx.events.RSLEvent;
	import mx.graphics.RectangularDropShadow;
	import mx.preloaders.IPreloaderDisplay;

	public class HPPreloader extends Sprite implements IPreloaderDisplay {
		
		private var _loadingLabelRect:Rectangle = new Rectangle(14, 17, 100, 16);
		private var _loadingDoneLabelRect:Rectangle = new Rectangle(115, 17, 20, 16);

		private var _xmlsLabelRect:Rectangle = new Rectangle(14, 34, 100, 16);
		private var _xmlsDoneLabelRect:Rectangle = new Rectangle(115, 34, 20, 16);
	
		private var _borderRect:Rectangle = new Rectangle(0, 0, stageWidth, 60);
	
		private var _xOffset:Number = 20;
		
		private var _yOffset:Number = 20;
		
		private var _loadingLabelObj:TextField;
		private var _loadingDoneLabelObj:TextField;

		private var _xmlsLabelObj:TextField;
		private var _xmlsDoneLabelObj:TextField;

		private var _showingDisplay:Boolean = false;
		
		private var _backgroundAlpha:Number = 1;
		
		private static var _instance:HPPreloader = null;
	
		public function get backgroundAlpha():Number {
			if (!isNaN(_backgroundAlpha))
				return _backgroundAlpha;
			else
				return 1;
		}
		
		public function set backgroundAlpha(value:Number):void {
			_backgroundAlpha = value;
		}
		
		private var _backgroundColor:uint;
	
		public function get backgroundColor():uint {
			return _backgroundColor;
		}
	
		public function set backgroundColor(value:uint):void {
			_backgroundColor = value;
		}
		
		public function get backgroundImage():Object {
			return null;
		}
		
		public function set backgroundImage(value:Object):void {
		}
		
		public function get backgroundSize():String {
			return null;
		}
		
		public function set backgroundSize(value:String):void {
		}
		
		private var _preloader:Sprite; 
		 
		public function set preloader(value:Sprite):void {
			_preloader = value;
			
//			trace("aaa " + Application.application);
		
			value.addEventListener(ProgressEvent.PROGRESS, HPApplicationManager.instance.applProgressHandler);	
//			value.addEventListener(Event.COMPLETE, completeHandler);
			
//			value.addEventListener(RSLEvent.RSL_PROGRESS, rslProgressHandler);
//			value.addEventListener(RSLEvent.RSL_COMPLETE, rslCompleteHandler);
			value.addEventListener(RSLEvent.RSL_ERROR, rslErrorHandler);
			
//			value.addEventListener(FlexEvent.INIT_PROGRESS, initProgressHandler);
			value.addEventListener(FlexEvent.INIT_COMPLETE, HPApplicationManager.instance.applInitCompleteHandler);
//			value.addEventListener(FlexEvent.INIT_COMPLETE, HPApplicationManager.instance.completeHandler);			

//			trace("preloader: " + Application.application);
			_instance = this;
		}
		
		public static function get instance():HPPreloader {
			return _instance;
		}
		
		private var _stageHeight:Number = 375;
	
		public function get stageHeight():Number {
			return _stageHeight;
		}
	
		public function set stageHeight(value:Number):void {
			_stageHeight = value;
		}
			
		private var _stageWidth:Number = 500;

		public function get stageWidth():Number {
			return _stageWidth;
		}
		
		public function set stageWidth(value:Number):void {
			_stageWidth = value;
		}
		
		private function get labelFormat():TextFormat {
			var tf:TextFormat = new TextFormat();
			tf.color = 0x333333;
			tf.font = "Verdana";
			tf.size = 10;
			return tf;
		}
	
		protected function get percentFormat():TextFormat {
			var tf:TextFormat = new TextFormat();
			tf.align = "right";
			tf.color  = 0x000000;
			tf.font = "Verdana";
			tf.size = 10;
			return tf;
		}
		
		public function initialize():void {
			center(stageWidth, stageHeight);
		}
		
		private function center(width:Number, height:Number):void	{
			_xOffset = Math.floor((width - _borderRect.width) / 2);
			_yOffset = Math.floor((height - _borderRect.height) / 2);
		}
		
		private function createChildren():void {
			var g:Graphics = graphics;
	
//			var labelObj:TextField;
//			var percentObj:TextField;
			
			// Draw the background first
			// Same value as StyleManager.NOT_A_COLOR. However, we don't want to bring in StyleManager at this point. 
//			if (backgroundColor != 0xFFFFFFFF)
//			{
//				g.beginFill(backgroundColor, backgroundAlpha);
//				g.drawRect(0, 0, stageWidth, stageHeight);
//			}

			g.beginFill(0x434343, backgroundAlpha);
			g.drawRect(0, (stageHeight-490)/2, stageWidth, 490);

					
//			_barFrameSprite = new Sprite();
//			_barSprite = new Sprite();
			
//			addChild(_barFrameSprite);	
//			addChild(_barSprite);
	
			// Draw the outside border and fill.
			g.beginFill(0xCCCCCC, 0.4);	
			g.drawRect(calcX(_borderRect.x),
					 		calcY(_borderRect.y),
					 		stageWidth,
					 		_borderRect.height);
			g.drawRect(calcX(_borderRect.x + 1),
						    calcY(_borderRect.y + 1),
						 	stageWidth - 2,
							_borderRect.height - 2);
			g.endFill();				
	
			g.beginFill(0xCCCCCC,0.4);
			g.drawRect(calcX(_borderRect.x + 1),
						 	calcY(_borderRect.y + 1),
						 	stageWidth - 2,
						 	_borderRect.height - 2);
			g.endFill();
			
//			var frame_g:Graphics = _barFrameSprite.graphics;
			
			// Draw the bar frame border and fill
//			var matrix:Matrix = new Matrix();
//			matrix.createGradientBox(_barFrameRect.width, _barFrameRect.height,
//									 Math.PI / 2, calcX(_barFrameRect.x), calcY(_barFrameRect.y));
			
//			frame_g.beginGradientFill(GradientType.LINEAR, 
//									  [ 0x5C6266, 0xB5B8BA ],
//									  [ 1.0, 1.0 ],
//									  [ 0, 0xFF ],
//									  matrix);
//			frame_g.drawRoundRect(calcX(_barFrameRect.x),
//								  calcY(_barFrameRect.y),
//								  _barFrameRect.width,
//								  _barFrameRect.height,
//								  _barFrameRect.cornerRadius * 2,
//								  _barFrameRect.cornerRadius * 2); 
//			frame_g.drawRoundRect(calcX(_barFrameRect.x + 1),
//								  calcY(_barFrameRect.y + 1),
//								  _barFrameRect.width - 2,
//								  _barFrameRect.height - 2,
//								  _barFrameRect.cornerRadius * 2,
//								  _barFrameRect.cornerRadius * 2);					  
//			frame_g.endFill();						  
	
			// Attach the label TextField.
			_loadingLabelObj = new TextField();
			_loadingLabelObj.x = calcX(_loadingLabelRect.x);
			_loadingLabelObj.y = calcY(_loadingLabelRect.y);
			_loadingLabelObj.width = _loadingLabelRect.width;
			_loadingLabelObj.height = _loadingLabelRect.height;			
			_loadingLabelObj.selectable = false;
			_loadingLabelObj.defaultTextFormat = labelFormat;
			addChild(_loadingLabelObj);
			
			_loadingDoneLabelObj = new TextField();
			_loadingDoneLabelObj.x = calcX(_loadingDoneLabelRect.x);
			_loadingDoneLabelObj.y = calcY(_loadingDoneLabelRect.y);
			_loadingDoneLabelObj.width = _loadingDoneLabelRect.width;
			_loadingDoneLabelObj.height = _loadingDoneLabelRect.height;			
			_loadingDoneLabelObj.selectable = false;
			_loadingDoneLabelObj.defaultTextFormat = labelFormat;
			addChild(_loadingDoneLabelObj);

			_xmlsLabelObj = new TextField();
			_xmlsLabelObj.x = calcX(_xmlsLabelRect.x);
			_xmlsLabelObj.y = calcY(_xmlsLabelRect.y);
			_xmlsLabelObj.width = _xmlsLabelRect.width;
			_xmlsLabelObj.height = _xmlsLabelRect.height;			
			_xmlsLabelObj.selectable = false;
			_xmlsLabelObj.defaultTextFormat = labelFormat;
			addChild(_xmlsLabelObj);
			
			_xmlsDoneLabelObj = new TextField();
			_xmlsDoneLabelObj.x = calcX(_xmlsDoneLabelRect.x);
			_xmlsDoneLabelObj.y = calcY(_xmlsDoneLabelRect.y);
			_xmlsDoneLabelObj.width = _xmlsDoneLabelRect.width;
			_xmlsDoneLabelObj.height = _xmlsDoneLabelRect.height;			
			_xmlsDoneLabelObj.selectable = false;
			_xmlsDoneLabelObj.defaultTextFormat = labelFormat;
			addChild(_loadingDoneLabelObj);
			
			
			// Attach the percentage TextField.
//			_percentObj = new TextField();
//			_percentObj.x = calcX(_percentRect.x);
//			_percentObj.y = calcY(_percentRect.y);
//			_percentObj.width = _percentRect.width;
//			_percentObj.height = _percentRect.height;			
//			_percentObj.selectable = false;
//			_percentObj.defaultTextFormat = percentFormat;
//			addChild(_percentObj);
			
			// Create dropshadow
			var ds:RectangularDropShadow = new RectangularDropShadow();
			ds.color = 0x000000;
			ds.angle = 90;
			ds.alpha = .6;
			ds.distance = 2;
			ds.tlRadius = 0;//ds.trRadius = ds.blRadius = ds.brRadius = _borderRect.cornerRadius;
			ds.drawShadow(g, calcX(_borderRect.x), calcY(_borderRect.y), stageWidth, _borderRect.height);
								  
			// Draw the top line		
			g.lineStyle(1,0xFFFFFF, .3);
			g.moveTo(calcX(_borderRect.x), calcY(_borderRect.y));
			g.lineTo(calcX(_borderRect.x) + stageWidth, calcY(_borderRect.y));				  
		}
		
		private function show():void {
			_showingDisplay = true;
			calcScale();
			draw();
//			_displayTime = getTimer(); // Time when the display is shown.
		}
		
		private function draw():void {
			setText(_loadingLabelObj, loadingArray[0]);
			setText(_xmlsLabelObj, xmlsArray[0]);
		}
		
		private function calcX(base:Number):Number {
			return base + _xOffset;
		}
		
		private function calcY(base:Number):Number {
			return base + _yOffset;
		}
		
		private function calcScale():void {
			if (stageWidth < 160 || stageHeight < 120)
			{
				scaleX = 1.0;
				scaleY = 1.0;
			}
			else if (stageWidth < 240 || stageHeight < 150)
			{
				// Scale to appropriate size
				createChildren();
				var scale:Number = Math.min(stageWidth / 240.0,
											stageHeight / 150.0);
				scaleX = scale;
				scaleY = scale;
			}
			else
			{
				createChildren();
			}
		}
		
		public function applProgressHandler():void {
//			trace("HPPreloader::progressHandler");
//			var loaded:uint = event.bytesLoaded;
//			var total:uint = event.bytesTotal;
			if (!_showingDisplay) {
	
//			var elapsedTime:int = getTimer() - _startTime;
			
			// Only show the Loading phase if it will appear for awhile.
//			if (_showingDisplay || showDisplayForDownloading(elapsedTime, event))		
//			{
//				if (!_startedLoading)
//				{
					show();

//					label = downloadingLabel;		
//					_startedLoading = true;
//				}
	
//				setProgress(event.bytesLoaded, event.bytesTotal);
//			}
			}
			progress(loadingArray, _loadingLabelObj);
		}
		
		public function xmlProgressHandler():void {
			progress(xmlsArray, _xmlsLabelObj);			
		}
		
		private var i:uint = 0;
		
		private var loadingArray:Array = ["Ładowanie", "Ładowanie.", "Ładowanie..", "Ładowanie..."];
		private var xmlsArray:Array = ["XML", "XML.", "XML..", "XML..."];
		
		private function progress(a:Array, labelObj:TextField):void {
			setText(labelObj, a[i]);
			i++;
			if (i == 4) {
				i = 0;
			}
		}
		
		private function setText(labelObj:TextField, s:String):void {
			if (labelObj) {
				labelObj.text = s;
			}
		}
		
		private function rslErrorHandler(event:RSLEvent):void {
			_preloader.removeEventListener(ProgressEvent.PROGRESS, HPApplicationManager.instance.applProgressHandler);	
			
//			_preloader.removeEventListener(Event.COMPLETE,
//										   completeHandler);
			
//			_preloader.removeEventListener(RSLEvent.RSL_PROGRESS,
//										   rslProgressHandler);
	
//			_preloader.removeEventListener(RSLEvent.RSL_COMPLETE,
//										   rslCompleteHandler);
	
			_preloader.removeEventListener(RSLEvent.RSL_ERROR,
										   rslErrorHandler);
			
//			_preloader.removeEventListener(FlexEvent.INIT_PROGRESS,
//										   initProgressHandler);
	
			_preloader.removeEventListener(FlexEvent.INIT_COMPLETE, HPApplicationManager.instance.applInitCompleteHandler);
		
//			if (!_showingDisplay)
//			{
//				show();
//				_showingDisplay = true;
//			}
	
//			label = "RSL Error " + (event.rslIndex + 1) + " of " + event.rslTotal;
			
		}
//		private function timerHandler():void {
	//		setProgress(100, 100);
//			ServiceHelper.invokeMethod(new CHService(), xmlComplete, xmlProgress, xmlIOError, "assets/xml/kapstelki.xml");
	
			//Application.application.dispatchEvent(new KapstelikiXMLParsedEvent(KapstelikiXMLParsedEvent.DONE));
			
//		}
		
		public function timerAllDone():void {
			var t:Timer = new Timer(1000, 1);
			t.addEventListener(TimerEvent.TIMER, allDone);
			t.start();
		}
		
		private function allDone(event:TimerEvent):void {
			dispatchEvent(new Event(Event.COMPLETE));		
			Application.application.dispatchEvent(new Event(Event.COMPLETE));
		}
		
		public function applInitCompleteHandler():void {
//			trace("HPPreloader::initCompleteHandler");
//			label = "Done";
			i = 0;
			setText(_loadingLabelObj, loadingArray[0]);
			setText(_loadingDoneLabelObj, "ok");
//			timerHandler();
//			var elapsedTime:int = getTimer() - _displayTime;
			
//			if (_showingDisplay && elapsedTime < MINIMUM_DISPLAY_TIME)
//			{
//				var timer:Timer = new Timer(MINIMUM_DISPLAY_TIME - elapsedTime, 1);
//				timer.addEventListener(TimerEvent.TIMER, timerHandler);
//				timer.start();
//			}
//			else
//			{
//				timerHandler();
//			}
		}
		
	}	
	
}